//
//  WSSQLiteManager.swift
//  微校园
//
//  Created by Gao on 16/12/28.
//  Copyright © 2016年 weSchool. All rights reserved.
//

import Foundation
import FMDB

enum WBNoticeType {
    case All
    case Receive
    case Send
}

/// SQLite 管理器
class WSSQLiteManager {
    
    /// 单例，全局数据库工具访问点
    static let shared = WSSQLiteManager()
    
    /// 数据库队列
    let queue: FMDatabaseQueue
    
    /// 构造函数
    private init() {
        
        // 数据库的全路径 - path
        let dbName = "weSchool.db"
        var path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
        path = (path as NSString).appendingPathComponent(dbName)
        
        print("数据库的路径 " + path)
        
        // 创建数据库队列，同时`创建或者打开`数据库
        queue = FMDatabaseQueue(path: path)
        
        // 打开数据库
        createTableNotice()

    }
}

// MARK: - 数据操作
extension WSSQLiteManager {
    /// 从数据库加载微通知据数组
    /// - parameter noticeType:   加载类型
    /// - parameter userId:   当前登录的用户帐号
    /// - parameter since_id: 返回ID比since_id大的通知
    /// - parameter max_id:   返回ID小于max_id的通知
    ///
    /// - returns: 微博的字典的数组，将数据库中 status 字段对应的二进制数据反序列化，生成字典
    func loadNotice(noticeType: WBNoticeType = .All, userId: String, since_id: Int64 = 0, max_id: Int64 = 0) -> [[String: AnyObject]] {
        return []
    }
    

    /// 新增或者修改通知数据
    ///
    /// - parameter userId: 当前登录用户的 id
    /// - parameter array:  从网路获取的`字典的数组`
    func updateNotice(userId: String, array: [[String: AnyObject]]){
        // 1. 准备 SQL
        /**
         CREATE TABLE IF NOT EXISTS "T_Notice" (
         "NID" INTEGER NOT NULL,
         "userId" INTEGER NOT NULL,
         "TEID" TEXT NOT NULL,
         "notice" TEXT,
         "createTime" TEXT DEFAULT (datetime('now', 'localtime')),
         PRIMARY KEY("NID","userId")
         );
         */
        let sql = "INSERT OR REPLACE INTO T_Notice (NID, userId, TEID, notice) VALUES (?, ?, ?, ?);"
        
        // 2. 执行 SQL
        queue.inTransaction { (db, rollback) in
            
//            // 遍历数组，逐条插入微博数据
//            for dict in array {
//                
//                // 从字典获取微博代号／将字典序列化成二进制数据
//                guard let statusId = dict["idstr"] as? String,
//                    let jsonData = try? JSONSerialization.data(withJSONObject: dict, options: [])
//                    else {
//                        continue
//                }
//                
//                // 执行 SQL
//                if db?.executeUpdate(sql, withArgumentsIn: [statusId, userId, ,jsonData]) == false {
//                    
//                    // 需要回滚 *rollback = YES;
//                    // Xcode 的自动语法转换，不会处理此处！
//                    // Swift 1.x & 2.x => rollback.memory = true;
//                    // Swift 3.0 的写法
//                    rollback?.pointee = true
//                    
//                    break
//                }
//            }
        }
    }    
}
    

// MARK: - 创建数据表
fileprivate extension WSSQLiteManager {
    /// 创建数据表
    func createTableNotice() {
        
        // 1. SQL
        guard let path = Bundle.main.path(forResource: "nitice.sql", ofType: nil),
            let sql = try? String(contentsOfFile: path)
            else {
                return
        }
        
        // print(sql)
        
        // 2. 执行 SQL - FMDB 的内部队列，串行队列，同步执行
        // 可以保证同一时间，只有一个任务操作数据库，从而保证数据库的读写安全！
        queue.inDatabase { (db) in
            
            // 只有在创表的时候，使用执行多条语句，可以一次创建多个数据表
            // 在执行增删改的时候，一定不要使用 statements 方法，否则有可能会被注入！
            if db?.executeStatements(sql) == true {
                print("创表成功")
            } else {
                print("创表失败")
            }
        }
        
        print("--- over")
    }
    
    /// 执行一个 SQL，返回字典的数组
    ///
    /// - parameter sql: sql
    ///
    /// - returns: 字典的数组
    func execRecordSet(sql: String) -> [[String: AnyObject]] {
        
        // 结果数组
        var result = [[String: AnyObject]]()
        
        // 执行 SQL - 查询数据，不会修改数据，所以不需要开启事务！
        // 事务的目的，是为了保证数据的有效性，一旦失败，回滚到初始状态！
        queue.inDatabase { (db) in
            
            guard let rs = db?.executeQuery(sql, withArgumentsIn: []) else {
                return
            }
            
            // 逐行 - 遍历结果集合
            while rs.next() {
                
                // 1> 列数
                let colCount = rs.columnCount()
                
                // 2> 遍历所有列
                for col in 0..<colCount {
                    
                    // 3> 列名 -> KEY / 值 -> Value
                    guard let name = rs.columnName(for: col),
                        let value = rs.object(forColumnIndex: col) else {
                            continue
                    }
                    
                    // print("\(name) - \(value)")
                    // 4> 追加结果
                    result.append([name: value as AnyObject])
                }
            }
        }
        
        return result
    }
}
